import { getMenuList, getBackMenuList } from '@/api/sys/menu';
import { getBackMenuListResultModel, getMappingMenuListResultModel } from '@/api/sys/model/menuModel';
import { PermissionModeEnum } from '@/enums/appEnum';
// import { useMessage } from '@/hooks/web/useMessage';
import { router } from '@/router';
import { transformRouteToMenu } from '@/router/helper/menuHelper';
import { transformObjToRoute, flatMultiLevelRoutes, filterRouteByBacklist } from '@/router/helper/routeHelper';
import { asyncRoutes, basicRootRoutes, backCustomRoutes } from '@/router/routes';
import { PAGE_NOT_FOUND_ROUTE } from '@/router/routes/basic';
import type { AppRouteRecordRaw, Menu } from '@/router/types';
import projectSetting from '@/settings/projectSetting';
import { filter } from '@/utils/helper/treeHelper';
import { defineStore } from 'pinia';
import { RouteRecordRaw } from 'vue-router';
import { store } from '..';
import { useAppStore } from './app';
import { useUserStore } from './user';

export const usePermissionStore = defineStore({
	id: 'app-permission',
	state: () => ({
		// 路由是否动态添加
		isDynamicAddedRoute: false,
		frontMenuList: [] as Menu[],
		backMenuList: [] as Menu[],
		// 触发菜单更新
		lastBuildMenuTime: 0,
	}),
	getters: {
		getIsDynamicAddedRoute(): boolean {
			return this.isDynamicAddedRoute;
		},
		getFrontMenuList(): Menu[] {
			return this.frontMenuList;
		},
		getBackMenuList(): Menu[] {
			return this.backMenuList;
		},
		getLastBuildMenuTime(): number {
			return this.lastBuildMenuTime;
		},
	},
	actions: {
		setDynamicAddedRoute(added: boolean) {
			this.isDynamicAddedRoute = added;
		},
		setFrontMenuList(list: Menu[]) {
			this.frontMenuList = list;
		},
		setBackMenuList(list: Menu[]) {
			this.backMenuList = list;
			list?.length > 0 && this.setLastBuildMenuTime();
		},
		setLastBuildMenuTime() {
			this.lastBuildMenuTime = new Date().getTime();
		},
		resetState(): void {
			this.isDynamicAddedRoute = false;
		},
		async buildRoutesAction() {
			const appStore = useAppStore();
			const userStore = useUserStore();

			let routes: AppRouteRecordRaw[] = [];
			const roleCodeList = userStore.getRoleInfo?.map(({ roleCode }) => roleCode) || [];
			const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig;

			const routeRoleFilter = (route: AppRouteRecordRaw) => {
				const codes = route.meta?.roleCode || [];
				if (!codes || !codes.length) return true;
				return roleCodeList.some(code => codes.includes(code));
			};

			const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => {
				const { meta } = route;
				const { ignoreRoute } = meta || {};
				return !ignoreRoute;
			};

			const patchHomeAffix = (routes: AppRouteRecordRaw[]) => {
				if (!routes || routes.length === 0) return;
				let homePath: string = userStore.getHomePath;
				function patcher(routes: AppRouteRecordRaw[], parentPath = '') {
					if (parentPath && parentPath !== '/') parentPath = parentPath + '/';
					routes.forEach((route: AppRouteRecordRaw) => {
						const { path, children, redirect } = route;
						const currentPath = path.startsWith('/') ? path : parentPath + path;
						if (currentPath === homePath) {
							if (redirect) {
								homePath = route.redirect! as string;
							} else {
								route.meta = Object.assign({}, route.meta, { affix: true });
								throw new Error('end');
							}
						}
						children && children.length > 0 && patcher(children, currentPath ? currentPath : '/');
					});
				}
				try {
					patcher(routes);
				} catch (e) {
					// 已处理完毕跳出循环
				}
				return;
			};

			switch (permissionMode) {
				case PermissionModeEnum.ROLE:
					routes = filter(asyncRoutes, routeRoleFilter);
					routes = routes.filter(routeRoleFilter);
					routes = flatMultiLevelRoutes(routes);
					break;
				// 前端维护路由全部信息，后台根据角色返回路由，过滤路由并生成菜单
				case PermissionModeEnum.ROUTE_MAPPING:
					let backRouteList = await getMenuList<getMappingMenuListResultModel>();

					// 过滤权限路由
					let routeList = filterRouteByBacklist(backRouteList, asyncRoutes);

					routeList = transformObjToRoute(routeList, true);

					const menuList = transformRouteToMenu(routeList);
					menuList.sort((a, b) => {
						return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0);
					});
					this.setFrontMenuList(menuList);

					routeList = filter(routeList, routeRemoveIgnoreFilter);
					routeList = routeList.filter(routeRemoveIgnoreFilter);

					routeList = flatMultiLevelRoutes(routeList);
					userStore.setHomePath(routeList[0].redirect as string);

					routes = [...routeList, ...basicRootRoutes];

					break;
				// 全部由后台返回
				case PermissionModeEnum.BACK:
					// const { createMessage } = useMessage();

					// createMessage.loading({
					// 	content: '菜单加载中...',
					// 	duration: 20,
					// });
					let backModeRouteList: AppRouteRecordRaw[] = [];
					try {
						// TODO: 从后台获取权限数据
						// await this.changePermissionCode();
						backModeRouteList =
							(await getBackMenuList<getBackMenuListResultModel>()) as AppRouteRecordRaw[];
					} catch (error) {
						console.error(error);
					}
					// 动态引入组件
					backModeRouteList = transformObjToRoute(backModeRouteList, true);

					// 后台路由到菜单结构
					const backMenuList = transformRouteToMenu([...backModeRouteList, ...backCustomRoutes]);
					this.setBackMenuList(backMenuList);

					// 删除 meta.ignoreRoute 项
					backModeRouteList = filter(backModeRouteList, routeRemoveIgnoreFilter);
					backModeRouteList = backModeRouteList.filter(routeRemoveIgnoreFilter);

					backModeRouteList = flatMultiLevelRoutes(backModeRouteList);
					userStore.setHomePath(backModeRouteList[0].redirect as string);

					routes = [...backModeRouteList, PAGE_NOT_FOUND_ROUTE, ...backCustomRoutes];
					break;
			}

			patchHomeAffix(routes);

			return routes;
		},
		generateRoutes(routes: AppRouteRecordRaw[]) {
			routes.forEach(route => {
				router.addRoute(route as unknown as RouteRecordRaw);
			});
			this.setDynamicAddedRoute(true);
		},
	},
});

export function usePermissionStoreOutside() {
	return usePermissionStore(store);
}
